#include "massage_bsp.h"
#include "massage_cfg.h"
#include "user_cfg.h"
#include "app.h"

/*在此添加马达相应部位的IO口*/
#define MOTOR1_HEAD_PORT                NULL
#define MOTOR1_HEAD_PIN                 NULL

#define MOTOR1_BACK_PORT                GpioPortA
#define MOTOR1_BACK_PIN                 GpioPin12

#define MOTOR1_LOIN_PORT                NULL
#define MOTOR1_LOIN_PIN                 NULL

#define MOTOR1_HIP_PORT                	GpioPortA
#define MOTOR1_HIP_PIN                 	GpioPin11

#define MOTOR1_LEG_PORT                	GpioPortA
#define MOTOR1_LEG_PIN                 	GpioPin8

#define MOTOR1_FOOT_PORT                GpioPortA
#define MOTOR1_FOOT_PIN                	GpioPin9

#define MOTOR1_NONE_PORT                NULL
#define MOTOR1_NONE_PIN                 NULL

#define MOTOR2_HEAD_PORT                NULL
#define MOTOR2_HEAD_PIN                 NULL

#define MOTOR2_BACK_PORT                GpioPortA
#define MOTOR2_BACK_PIN                 GpioPin15

#define MOTOR2_LOIN_PORT                NULL
#define MOTOR2_LOIN_PIN                 NULL

#define MOTOR2_HIP_PORT                	GpioPortA
#define MOTOR2_HIP_PIN                 	GpioPin10

#define MOTOR2_LEG_PORT                 NULL
#define MOTOR2_LEG_PIN                  NULL

#define MOTOR2_FOOT_PORT                NULL
#define MOTOR2_FOOT_PIN                 NULL

#define MOTOR2_NONE_PORT                NULL
#define MOTOR2_NONE_PIN                 NULL

const gpio_info_t msg_info[][7] = {
    {
        {MOTOR1_NONE_PORT, MOTOR1_NONE_PIN},
        {MOTOR1_FOOT_PORT, MOTOR1_FOOT_PIN},
        {MOTOR1_LEG_PORT, MOTOR1_LEG_PIN},
        {MOTOR1_HIP_PORT, MOTOR1_HIP_PIN},
        {MOTOR1_LOIN_PORT, MOTOR1_LOIN_PIN},
        {MOTOR1_BACK_PORT, MOTOR1_BACK_PIN},
        {MOTOR1_HEAD_PORT, MOTOR1_HEAD_PIN},				
    },
    {
        {MOTOR2_NONE_PORT, MOTOR2_NONE_PIN},
        {MOTOR2_FOOT_PORT, MOTOR2_FOOT_PIN},
        {MOTOR2_LEG_PORT, MOTOR2_LEG_PIN},
        {MOTOR2_HIP_PORT, MOTOR2_HIP_PIN},
        {MOTOR2_LOIN_PORT, MOTOR2_LOIN_PIN},
        {MOTOR2_BACK_PORT, MOTOR2_BACK_PIN},
        {MOTOR2_HEAD_PORT, MOTOR2_HEAD_PIN},				
    },

};
 
#if MSG_STATUS_CHECK
void Msg_Status_Get(void) 
{
    /*在此添加端口初始化代码*/
    stc_gpio_config_t pstcGpioCfg;
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    ///< 端口方向配置->输入
    pstcGpioCfg.enDir = GpioDirIn;
    ///< 端口驱动能力配置->高驱动能力
    pstcGpioCfg.enDrv = GpioDrvH;
    ///< 端口上下拉配置->上拉
    pstcGpioCfg.enPuPd = GpioPu;
    ///< 端口开漏输出配置->开漏输出关闭
    pstcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    pstcGpioCfg.enCtrlMode = GpioAHB;
    
    // 在GPIO初始化之前先对马达安装情况进行检测，若马达部位对应的电阻为NC，则表示该马达部位不需要控制
    // 将马达控制IO口初始化为上拉输入,以便进行IO状态检测
    for (uint8_t i = 0; i < (sizeof(msg_info)/sizeof(msg_info[0])); i++) {
        Gpio_Init(msg_info[i][1].port, msg_info[i][1].pin, &pstcGpioCfg);
        Gpio_Init(msg_info[i][2].port, msg_info[i][2].pin, &pstcGpioCfg);
        Gpio_Init(msg_info[i][3].port, msg_info[i][3].pin, &pstcGpioCfg);
        Gpio_Init(msg_info[i][4].port, msg_info[i][4].pin, &pstcGpioCfg);
        Gpio_Init(msg_info[i][5].port, msg_info[i][5].pin, &pstcGpioCfg);
        Gpio_Init(msg_info[i][6].port, msg_info[i][6].pin, &pstcGpioCfg);

        // 在此添加对应马达部位的IO状态检测
        if (Gpio_GetInputIO(msg_info[i][1].port, msg_info[i][1].pin)) {
            msg_para[i].msg_install.pos.foot = TRUE;
        }
        if (Gpio_GetInputIO(msg_info[i][2].port, msg_info[i][2].pin)) {
            msg_para[i].msg_install.pos.leg = TRUE;
        }
        if (Gpio_GetInputIO(msg_info[i][3].port, msg_info[i][3].pin)) {
            msg_para[i].msg_install.pos.hip = TRUE;
        }
        if (Gpio_GetInputIO(msg_info[i][4].port, msg_info[i][4].pin)) {
            msg_para[i].msg_install.pos.loin = FALSE;//TRUE;
        }
        if (Gpio_GetInputIO(msg_info[i][5].port, msg_info[i][5].pin)) {
            msg_para[i].msg_install.pos.back = TRUE;
        }
        if (Gpio_GetInputIO(msg_info[i][6].port, msg_info[i][6].pin)) {
            msg_para[i].msg_install.pos.head = FALSE;//TRUE;
        }
    }
}
#endif

void Msg_Init_Port(void)
{
    /*在此添加端口初始化代码*/
    stc_gpio_config_t pstcGpioCfg;
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
 
    ///< 端口方向配置->输出
    pstcGpioCfg.enDir = GpioDirOut;
    ///< 端口驱动能力配置->高驱动能力
    pstcGpioCfg.enDrv = GpioDrvH;
    ///< 端口上下拉配置->无上下拉
    pstcGpioCfg.enPuPd = GpioNoPuPd;
    ///< 端口开漏输出配置->开漏输出关闭
    pstcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    pstcGpioCfg.enCtrlMode = GpioAHB;
    
    for (uint8_t i = 0; i < (sizeof(msg_info)/sizeof(msg_info[0])); i++) {
        Gpio_Init(msg_info[i][1].port, msg_info[i][1].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][1].port, msg_info[i][1].pin);
        Gpio_Init(msg_info[i][2].port, msg_info[i][2].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][2].port, msg_info[i][2].pin);
        Gpio_Init(msg_info[i][3].port, msg_info[i][3].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][3].port, msg_info[i][3].pin);
        Gpio_Init(msg_info[i][4].port, msg_info[i][4].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][4].port, msg_info[i][4].pin);
        Gpio_Init(msg_info[i][5].port, msg_info[i][5].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][5].port, msg_info[i][5].pin);
        Gpio_Init(msg_info[i][6].port, msg_info[i][6].pin, &pstcGpioCfg);
        Gpio_ClrIO(msg_info[i][6].port, msg_info[i][6].pin);
    }
}

void Msg_Opt_Port(uint8_t dev, msg_pos_t pos_sel, msg_sta_t sta)
{
    /*在此添加马达打开和关闭代码*/
    if (sta) {
        #if MSG_OVER_CURRENT_DETECTION
        // 避免当模拟比较器中断发生在该函数内所造成的bug（没有发生短路的马达部位被判断为短路的bug）
        // 若出现上述所描述的bug几率仍然较高，则可将基于库函数操作GPIO口的方式改为基于寄存器操作
        if (!msg_para[dev].oc_flag) {
        #endif
            // Gpio_SetIO(msg_info[dev][pos_sel].port, msg_info[dev][pos_sel].pin);
            Gpio_SetIO(msg_info[0][pos_sel].port, msg_info[0][pos_sel].pin);
            Gpio_SetIO(msg_info[1][pos_sel].port, msg_info[1][pos_sel].pin);
        #if MSG_OVER_CURRENT_DETECTION
        }
        #endif
    } else {
        // Gpio_ClrIO(msg_info[dev][pos_sel].port, msg_info[dev][pos_sel].pin);
            Gpio_ClrIO(msg_info[0][pos_sel].port, msg_info[0][pos_sel].pin);
            Gpio_ClrIO(msg_info[1][pos_sel].port, msg_info[1][pos_sel].pin);
    }
}

#if MSG_OVER_CURRENT_DETECTION
void Msg_Oc_Check_Opt_Port(uint8_t dev, msg_pos_t pos_sel, msg_sta_t sta)
{
    /*在此添加马达打开和关闭代码*/
    if (sta) {
        // 避免当模拟比较器中断发生在该函数内所造成的bug（没有发生短路的马达部位被判断为短路的bug）
        // 若出现上述所描述的bug几率仍然较高，则可将基于库函数操作GPIO口的方式改为基于寄存器操作
        if (msg_para[dev].oc_flag) {
            Gpio_SetIO(msg_info[dev][pos_sel].port, msg_info[dev][pos_sel].pin);
            Gpio_SetIO(msg_info[0][pos_sel].port, msg_info[0][pos_sel].pin);
            Gpio_SetIO(msg_info[1][pos_sel].port, msg_info[1][pos_sel].pin);
        }
    } else {
        Gpio_ClrIO(msg_info[dev][pos_sel].port, msg_info[dev][pos_sel].pin);
        Gpio_ClrIO(msg_info[0][pos_sel].port, msg_info[0][pos_sel].pin);
        Gpio_ClrIO(msg_info[1][pos_sel].port, msg_info[1][pos_sel].pin);
    }
}
#endif

uint32_t Msg_Clk_Get(void)
{
    /** 在此添加代码 返回一个1ms的时钟 */

    /** example:   */
    /** extern unsigned int value;  // 在1ms定时器中递增value*/
    /** clk = value; */

    /** ********************************/

    uint32_t clk;
    clk = app_para.msg_clk;
    return clk;
}
